package org.zachary.prosocialbehaviorservice.application;

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.zachary.commonmodule.entity.MqTransmissionJson;
import org.zachary.prosocialbehaviorservice.application.command.JoinExitActivityCommand;
import org.zachary.prosocialbehaviorservice.domain.aggregate_model.activity.Activity;
import org.zachary.prosocialbehaviorservice.domain.aggregate_model.activity.ActivityToItem;
import org.zachary.prosocialbehaviorservice.domain.aggregate_model.activity_user.UserJoinActivityDTO;
import org.zachary.prosocialbehaviorservice.domain.aggregate_model.activity.ActivityItem;
import org.zachary.prosocialbehaviorservice.domain.aggregate_model.activity_user.UserActivity;
import org.zachary.prosocialbehaviorservice.domain.aggregate_model.activity_user.event.ExitActivityEvent;
import org.zachary.prosocialbehaviorservice.domain.aggregate_model.activity_user.event.FinishedItemEvent;
import org.zachary.prosocialbehaviorservice.domain.repository.ActivityItemRepository;
import org.zachary.prosocialbehaviorservice.domain.repository.ActivityToItemRepository;
import org.zachary.prosocialbehaviorservice.domain.repository.UserActivityParticipationRepository;
import org.zachary.prosocialbehaviorservice.infrastructure.utils.UUIdUtil;

import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class UserActivityService {
    private final UserActivityParticipationRepository userActivityParticipationRepository;
    private final ApplicationEventPublisher eventPublisher;
    private final ActivityItemRepository activityItemRepository;
    private final KafkaProducer kafkaProducer;
    private final ActivityService activityService;
    private final ActivityItemService activityItemService;
    private final ActivityToItemRepository activityToItemRepository;

    public UserActivityService(UserActivityParticipationRepository userActivityParticipationRepository, ApplicationEventPublisher eventPublisher, ActivityItemRepository activityItemRepository, KafkaProducer kafkaProducer, ActivityService activityService, ActivityItemService activityItemService, ActivityToItemRepository activityToItemRepository) {
        this.userActivityParticipationRepository = userActivityParticipationRepository;
        this.eventPublisher = eventPublisher;
        this.activityItemRepository = activityItemRepository;
        this.kafkaProducer = kafkaProducer;
        this.activityService = activityService;
        this.activityItemService = activityItemService;
        this.activityToItemRepository = activityToItemRepository;
    }

    @Transactional
    public void join(JoinExitActivityCommand command){
        UserActivity isExit = userActivityParticipationRepository.findByUserItemId(command.userId(), command.itemId());
        if(isExit != null){
            throw new RuntimeException("不能重复参与");
        }
        ActivityItem item = activityItemRepository.findById(command.itemId());
        if(item==null){
            throw new RuntimeException("没有此活动");
        }
        item.decrementByOne();
        activityItemRepository.decrementByOne(command.itemId());

        UserActivity ua=UserActivity.create(
                command.userId(),
                command.itemId(),
                false,
                Instant.now(),
                Instant.now()
        );
        ua.join();
        userActivityParticipationRepository.joinActivity(ua);
    }

    @Transactional
    public void exit(Integer userId, Integer itemId) {
        ActivityItem item = activityItemRepository.findById(itemId);
        if(item==null){
            throw new RuntimeException("没有此活动");
        }
        eventPublisher.publishEvent(new ExitActivityEvent(userId,itemId));
        userActivityParticipationRepository.exitActivity(userId,itemId);
    }
    @Transactional
    public List<UserJoinActivityDTO> list(Integer userId){
        return userActivityParticipationRepository.findUserJoinActivities(userId);
    }


    public void finishedItem(JoinExitActivityCommand command) {
        UserActivity ua=userActivityParticipationRepository.findByUserItemId(command.userId(),command.itemId());
        if(ua==null){
            throw new RuntimeException("该用户没有参与此活动！");
        }

        ActivityItem item = activityItemRepository.findById(command.itemId());
        if (item.getEndDate().isBefore(Instant.now())) {
            throw new RuntimeException("活动已结束");
        }
        Integer activityId=activityItemService.findActivityIdByItemId(command.itemId()).orElse(null);
        Activity activity=activityService.findById(activityId).orElse(null);
        eventPublisher.publishEvent(new FinishedItemEvent(command));
        userActivityParticipationRepository.finished(command.userId(),command.itemId());
        assert activity != null;
        MqTransmissionJson mq=new MqTransmissionJson(
                UUIdUtil.createUUId(),
                command.userId(),
                ServiceIntegerConverter(activity.getTitle()),
                false,
                0,
                false,
                0.00,
                "亲社会行为："+item.getTitle(),
                item.getStartDate(),
                Instant.now()
        );
        System.out.println(mq);
        kafkaProducer.sendJsonMessage(mq);
    }
    private static Integer ServiceIntegerConverter(String input){
        return switch (input){
            case "护水卫士"->1;
            case "资源回收"->2;
            case "公益之星"->3;
            default -> throw new RuntimeException("不存在该活动类型");
        };
    }
}
